package com.ubi.core.framework.queue;

import com.ubi.core.framework.spring.SpringObjectFactory;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class PollingWorker<T> {

    private static final int DEFAULT_SHUTDOWN_AWAIT_SECONDS = 15;

    private int pollingTaskSize;

    private Queue<T> queue;

    private Class<? extends PollingTask<T>> pollingTaskClass;

    private List<PollingTask<T>> pollingTasks;

    private SpringObjectFactory springObjectFactory;

    private ExecutorService executorService;

    public void initialize() {
        for (int i = 0; i < pollingTaskSize; i++) {
            PollingTask<T> pollingTask = springObjectFactory.createBean(pollingTaskClass);
            pollingTask.setPollingQueue(queue);
            pollingTasks.add(pollingTask);
        }
    }

    @PostConstruct
    public void startup() {
        for (PollingTask<T> pollingTask : pollingTasks) {
            executorService.execute(pollingTask);
        }
    }

    @PreDestroy
    public void shutdown() throws InterruptedException {
        executorService.shutdown();
        executorService.awaitTermination(DEFAULT_SHUTDOWN_AWAIT_SECONDS, TimeUnit.HOURS);
    }

    public void setPollingTaskSize(int pollingTaskSize) {
        this.pollingTaskSize = pollingTaskSize;
        executorService = Executors.newFixedThreadPool(pollingTaskSize);
        pollingTasks = new ArrayList<>(pollingTaskSize);
    }

    public void setQueue(Queue<T> queue) {
        this.queue = queue;
    }

    public void setSpringObjectFactory(SpringObjectFactory springObjectFactory) {
        this.springObjectFactory = springObjectFactory;
    }

    public void setPollingTaskClass(Class<? extends PollingTask<T>> pollingTaskClass) {
        this.pollingTaskClass = pollingTaskClass;
    }

}
